deploy: Set the immutable bit on the deployment root
authorColin Walters <walters@verbum.org>
Fri, 30 May 2014 14:02:01 +0000 (10:02 -0400)
committerColin Walters <walters@verbum.org>
Tue, 3 Jun 2014 17:41:48 +0000 (13:41 -0400)
This prevents people from creating new directories there and expecting
them to be persisted.  The OSTree model has all local state to be in
/etc and /var.

This introduces a compile-time dependency on libe2fsprogs.

We're only doing this for the root directory at the moment.

https://bugzilla.gnome.org/show_bug.cgi?id=728006

Makefile-libostree.am
configure.ac
src/libostree/ostree-linuxfsutil.c [new file with mode: 0644]
src/libostree/ostree-linuxfsutil.h [new file with mode: 0644]
src/libostree/ostree-sysroot-cleanup.c
src/libostree/ostree-sysroot-deploy.c

index eca57ea54c8922d9b13dbaee06b0a61337579193..1b7560014345070e8d639d94a7bac9a030b77c73 100644 (file)
@@ -49,6 +49,8 @@ libostree_1_la_SOURCES = \
        src/libostree/ostree-lzma-decompressor.h \
        src/libostree/ostree-varint.h \
        src/libostree/ostree-varint.c \
+       src/libostree/ostree-linuxfsutil.h \
+       src/libostree/ostree-linuxfsutil.c \
        src/libostree/ostree-diff.c \
        src/libostree/ostree-mutable-tree.c \
        src/libostree/ostree-repo.c \
index 74094c9c0b90056bd010564675080a33f587da87..1b3916bb9a4157ee55445d8fcba61f83ff6f120f 100644 (file)
@@ -48,6 +48,9 @@ PKG_CHECK_MODULES(OT_DEP_GIO_UNIX, $GIO_DEPENDENCY)
 dnl 5.1.0 is an arbitrary version here
 PKG_CHECK_MODULES(OT_DEP_LZMA, liblzma >= 5.1.1alpha)
 
+dnl We're not actually linking to this, just using the header
+PKG_CHECK_MODULES(OT_DEP_E2P, e2p)
+
 SOUP_DEPENDENCY="libsoup-2.4 >= 2.39.1"
 AC_ARG_WITH(soup,
            AS_HELP_STRING([--with-soup], [Use libsoup @<:@default=yes@:>@]),
diff --git a/src/libostree/ostree-linuxfsutil.c b/src/libostree/ostree-linuxfsutil.c
new file mode 100644 (file)
index 0000000..8e11d2c
--- /dev/null
@@ -0,0 +1,128 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2014 Colin Walters <walters@verbum.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "ostree-linuxfsutil.h"
+#include "otutil.h"
+#include "libgsystem.h"
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <ext2fs/ext2_fs.h>
+
+/**
+ * _ostree_linuxfs_fd_alter_immutable_flag:
+ * @fd: A file descriptor
+ * @new_immutable_state: Set this to %TRUE to make the file immutable, %FALSE to unset the flag
+ * @cancellable: Cancellable
+ * @error: GError
+ *
+ * Alter the immutable flag of object referred to by @fd; may be a
+ * regular file or a directory.
+ *
+ * If the operation is not supported by the underlying filesystem,
+ * this function will silently do nothing.
+ */
+gboolean
+_ostree_linuxfs_fd_alter_immutable_flag (int            fd,
+                                         gboolean       new_immutable_state,
+                                         GCancellable  *cancellable,
+                                         GError       **error)
+{
+  gboolean ret = FALSE;
+  unsigned long flags;
+  int r;
+
+  r = ioctl (fd, EXT2_IOC_GETFLAGS, &flags);
+  if (r == -1)
+    {
+      int errsv = errno;
+      if (errsv == EOPNOTSUPP || errsv == ENOTTY)
+        ;
+      else
+        {
+          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                       "ioctl(EXT2_IOC_GETFLAGS): %s",
+                       g_strerror (errsv));
+          goto out;
+        }
+    }
+  else
+    {
+      if (new_immutable_state)
+        flags |= EXT2_IMMUTABLE_FL;
+      else
+        flags &= ~EXT2_IMMUTABLE_FL;
+      r = ioctl (fd, EXT2_IOC_SETFLAGS, &flags);
+      if (r == -1)
+        {
+          int errsv = errno;
+          if (errsv == EOPNOTSUPP || errsv == ENOTTY)
+            ;
+          else
+            {
+              g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                           "ioctl(EXT2_IOC_GETFLAGS): %s",
+                           g_strerror (errsv));
+              goto out;
+            }
+        }
+    }
+
+  ret = TRUE;
+ out:
+  return ret;
+}
+
+gboolean
+_ostree_linuxfs_alter_immutable_flag (GFile         *path,
+                                      gboolean       new_immutable_state,
+                                      GCancellable  *cancellable,
+                                      GError       **error)
+{
+  gboolean ret = FALSE;
+  int fd = -1;
+
+  if (g_cancellable_set_error_if_cancelled (cancellable, error))
+    return FALSE;
+
+  fd = open (gs_file_get_path_cached (path), O_RDONLY|O_NONBLOCK|O_LARGEFILE);
+  if (fd == -1)
+    {
+      int errsv = errno;
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "open(%s): %s",
+                   gs_file_get_path_cached (path),
+                   g_strerror (errsv));
+      goto out;
+    }
+
+  if (!_ostree_linuxfs_fd_alter_immutable_flag (fd, new_immutable_state,
+                                                cancellable, error))
+    goto out;
+
+  ret = TRUE;
+ out:
+  if (fd != -1)
+    (void) close (fd);
+  return ret;
+}
+
diff --git a/src/libostree/ostree-linuxfsutil.h b/src/libostree/ostree-linuxfsutil.h
new file mode 100644 (file)
index 0000000..566717c
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2014 Colin Walters <walters@verbum.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#pragma once
+
+#include "ostree-types.h"
+
+G_BEGIN_DECLS
+
+gboolean
+_ostree_linuxfs_fd_alter_immutable_flag (int            fd,
+                                         gboolean       new_immutable_state,
+                                         GCancellable  *cancellable,
+                                         GError       **error);
+
+gboolean
+_ostree_linuxfs_alter_immutable_flag (GFile         *path,
+                                      gboolean       new_immutable_state,
+                                      GCancellable  *cancellable,
+                                      GError       **error);
+
+G_END_DECLS
+
index ade75bbaf114e29d0f1243a07b465dd8ece8bfaf..825d6c4d41782f1444eab3699b4e43ac320213a6 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "otutil.h"
 #include "libgsystem.h"
+#include "ostree-linuxfsutil.h"
 
 #include "ostree-sysroot-private.h"
 
@@ -341,6 +342,9 @@ cleanup_old_deployments (OstreeSysroot       *self,
           if (device == root_device && inode == root_inode)
             continue;
 
+          if (!_ostree_linuxfs_alter_immutable_flag (deployment_path, FALSE,
+                                                     cancellable, error))
+            goto out;
           if (!gs_shutil_rm_rf (deployment_path, cancellable, error))
             goto out;
           if (!gs_shutil_rm_rf (origin_path, cancellable, error))
index f74fd922102e2bb65103042789bfe001a41cfd1f..d5456c05544ca2cd791a55cbdf14b0bef2a671e8 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "ostree-sysroot-private.h"
 #include "ostree-core-private.h"
+#include "ostree-linuxfsutil.h"
 #include "otutil.h"
 #include "libgsystem.h"
 
@@ -1715,6 +1716,10 @@ ostree_sysroot_deploy_tree (OstreeSysroot     *self,
                                       cancellable, error))
     goto out;
 
+  if (!_ostree_linuxfs_alter_immutable_flag (new_deployment_path, TRUE,
+                                             cancellable, error))
+    goto out;
+
   /* After this, install_deployment_kernel() will set the other boot
    * options and write it out to disk.
    */